package com.kan.awaits;

import java.sql.Connection;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.kan.awaits.exception.DBAccessException;
import com.kan.awaits.validate.Validator;

public class Updator<T>
{
	private Connection connection;

	private static Log logger = LogFactory.getLog(Updator.class);

	private HashMap<Class<?>, TableMeta<?>> tableMetas;

	private Map<String, Object> changeMap = new HashMap<String, Object>();

	private List<Restriction> restrictions = new Vector<Restriction>();

	private List<Object> values = new Vector<Object>();

	Class<T> clazz;

	public Updator<T> set(String cname, Object value)
	{
		changeMap.put(cname, value);
		return this;
	}

	public static <T> Updator<T> get(Class<T> type, Connection connection, HashMap<Class<?>, TableMeta<?>> tableMetas)
	{
		Updator<T> updator = new Updator<T>();
		updator.clazz = type;
		updator.connection = connection;
		updator.tableMetas = tableMetas;
		return updator;
	}

	static final String UPDATE = "UPDATE ";
	static final String SET = " SET ";
	final static String WHERE = " WHERE ";

	public int update() throws DBAccessException
	{
		StringBuffer sql = new StringBuffer();
		sql.append(UPDATE)//
				.append(tableMetas.get(clazz).getTableName())//
				.append(SET);

		StringBuffer a = new StringBuffer();
		int i = 0;
		for (String c : changeMap.keySet())
		{
			a.append(c).append(" = ? ");
			values.add(changeMap.get(c));
			if (i < changeMap.keySet().size() - 1)
			{
				a.append(",");
			}
			i++;
		}

		sql.append(a);
		if (Validator.notEmpty(restrictions))
		{
			sql.append(WHERE);
			boolean firstFlg = true;
			for (Restriction restriction : restrictions)
			{
				if (firstFlg)
				{
					sql.append(restriction.getSql());
					firstFlg = false;
				} else
				{
					sql.append(" AND ").append(restriction.getSql());
				}
				values.addAll(Arrays.asList(restriction.getValues()));
			}
		}
		return DBHelper.update(connection, sql.toString(), values.toArray(new Object[0]));
	}

	public Updator<T> add(Restriction restriction)
	{
		restrictions.add(restriction);
		return this;
	}

	public String getTableName()
	{
		return tableMetas.get(clazz).getTableName();
	}

	protected String buildSql()
	{
		StringBuffer sb = new StringBuffer();
		sb.append("");
		return sb.toString();
	}
}
